package com.freecycle.sg.ui;

import java.util.ArrayList;
import java.util.List;

import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;

import com.freecycle.sg.R;
import com.freecycle.sg.sqlite.Freebie.Freebies;
import com.freecycle.sg.utils.ActivityHelper;
import com.freecycle.sg.utils.Config;
import com.freecycle.sg.utils.ConnectionHelper;
import com.freecycle.sg.utils.LocationHelper;
import com.freecycle.sg.utils.ReferenceHelper;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

public class HomeActivity extends MapActivity implements LocationListener {

	/*private static final String TAG = "HomeActivity";*/

	private MapView mapview;
	private MapController mController;
	private List<Overlay> mOverlays;

	private LocationManager mLocationManager;
	private LocationHelper mLocationHelper;

	private Location curLocation;
	private int maxZoomLevel;
	
	private ProgressDialog dialog;
	private PointerOverlay pin;

	@Override
	protected void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		
		if (!ConnectionHelper.isWifiEnable(this)) {
			ConnectionHelper.toEnableWifi(this).show();
		}
		
		if (!ReferenceHelper.hasDownloadedRefData(this)) {
			ReferenceHelper.downloadRefData(this);
		}
		
		setContentView(R.layout.map);
		getActivityHelper().setupActionBar("", 0);

		mapview = (MapView) findViewById(R.id.mapview);
		mController = mapview.getController();
		mapview.setBuiltInZoomControls(true);
		
		mOverlays = mapview.getOverlays();
		maxZoomLevel = mapview.getMaxZoomLevel();
		mController.setZoom(maxZoomLevel - 5);

		mLocationHelper = new LocationHelper(this);
		mLocationManager = mLocationHelper.getLocationManager();
		curLocation = mLocationManager.getLastKnownLocation(mLocationHelper
				.getLowAccProvider().getName());
		
		// Show last known location
		pin = new PointerOverlay(getResources().getDrawable(R.drawable.marker_generic));
		if (curLocation != null) {
			final GeoPoint location = new GeoPoint(
					(int) (curLocation.getLatitude() * 1e6), 
					(int) (curLocation.getLongitude() * 1e6));

			moveToLocation(pin, location, (maxZoomLevel - 2));
		} else {
			final GeoPoint location = new GeoPoint(
					(int) (Config.sgLatitude * 1e6), 
					(int) (Config.sgLongitude * 1e6));
			
			moveToLocation(pin, location, Math.round(maxZoomLevel - maxZoomLevel / 2));
		}
		
		
	}

	private void moveToLocation(PointerOverlay pin, final GeoPoint location, int zoomLevel) {
		OverlayItem pinOverlayItem = new OverlayItem(location, 
				"lat:" + location.getLatitudeE6(), "long:" + location.getLongitudeE6());
		pin.addOverlay(pinOverlayItem);

		if (mOverlays != null && mController != null) {
			mOverlays.add(pin);
			mController.animateTo(location);
			mController.setZoom(zoomLevel);
		}
	}

	@Override
	public void onResume() {
		super.onResume();
		mLocationManager.requestLocationUpdates(mLocationHelper
				.getLowAccProvider().getName(), 0, 0, this);
		showDialog(Config.DIALOG_LOADING);
	}

	@Override
	public void onPause() {
		super.onPause();
		mLocationManager.removeUpdates(this);
	}
	
	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case Config.DIALOG_LOADING:
			dialog = new ProgressDialog(this);
			dialog.setCancelable(false);
			dialog.setIndeterminate(true);
			dialog.setMessage("Getting current location...");
			return dialog;

		default:
			return super.onCreateDialog(id);
		}
	}

	/*************************************************************************/
	@Override
	public void onLocationChanged(Location location) {
		if (dialog != null && dialog.isShowing()) {
			dialog.dismiss();
		}
		
		if (location != null) {
			final GeoPoint p = new GeoPoint(
					(int) (location.getLatitude() * 1e6),
					(int) (location.getLongitude() * 1e6));

			moveToLocation(pin, p, (maxZoomLevel - 2));
		}
	}

	@Override
	public void onProviderDisabled(String provider) {

	}

	@Override
	public void onProviderEnabled(String provider) {

	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {

	}

	/*************************************************************************/
	final ActivityHelper mActivityHelper = ActivityHelper.createInstance(this);

	protected ActivityHelper getActivityHelper() {
		return mActivityHelper;
	}

	@Override
	protected void onPostCreate(Bundle savedInstanceState) {
		super.onPostCreate(savedInstanceState);
		mActivityHelper.onPostCreate(savedInstanceState);
	}

	@Override
	public boolean onKeyLongPress(int keyCode, KeyEvent event) {
		return mActivityHelper.onKeyLongPress(keyCode, event)
				|| super.onKeyLongPress(keyCode, event);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.map_menu_items, menu);
		getMenuInflater().inflate(R.menu.refresh_menu_items, menu);
		getMenuInflater().inflate(R.menu.add_menu_items, menu);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_map:
			final Intent intent = new Intent(HomeActivity.this, FreebieListActivity.class);
			intent.putExtra(Intent.EXTRA_STREAM, curLocation);
			startActivity(intent);
			return true;
		case R.id.menu_refresh:
			if (curLocation != null) {
				final GeoPoint p = new GeoPoint(
						(int) (curLocation.getLatitude() * 1e6),
						(int) (curLocation.getLongitude() * 1e6));

				moveToLocation(pin, p, (maxZoomLevel - 2));
			}
			return true;
		case R.id.menu_add:
			final Intent i= new Intent(Intent.ACTION_INSERT);
	        i.setType(Freebies.CONTENT_ITEM_TYPE);
			startActivity(i);
			return true;

		default:
			return super.onOptionsItemSelected(item);
		}
	}

	/*************************************************************************/
	@Override
	protected boolean isRouteDisplayed() {
		return true;
	}
	
	@Override
	protected boolean isLocationDisplayed() {
		return true;
	}

	/*************************************************************************/
	private class PointerOverlay extends ItemizedOverlay<OverlayItem> {

		private ArrayList<OverlayItem> mOverlays;

		public PointerOverlay(Drawable defaultMarker) {
			super(boundCenterBottom(defaultMarker));
			mOverlays = new ArrayList<OverlayItem>();
			populate();
		}

		@Override
		protected OverlayItem createItem(int i) {
			return mOverlays.get(i);
		}

		public void addOverlay(OverlayItem item) {
			mOverlays.add(item);
			populate();
		}

		@Override
		protected boolean onTap(int index) {
			return true;
		}

		@Override
		public int size() {
			return mOverlays.size();
		}

	}

}
